package cn.anecansaitin.whimsy.common.capabilities;

import net.minecraft.nbt.CompoundTag;
import net.neoforged.neoforge.common.util.INBTSerializable;

import java.util.HashMap;
import java.util.Map;

public class RockScepterManaStorage implements IManaStorage, INBTSerializable<CompoundTag> {
    public static final String DIORITE_TYPE = "diorite";
    private final Map<String, ManaType> mana = new HashMap<>();

    public RockScepterManaStorage() {
        mana.put(DIORITE_TYPE, new ManaType(DIORITE_TYPE, 0, 10000, 1000, 1000, 0xdfdfdf));
    }

    @Override
    public int receiveMana(String manaType, int maxReceive, boolean simulate) {
        ManaType mana = this.mana.getOrDefault(manaType, null);

        if (mana == null) {
            return 0;
        }

        if (!canReceive(mana)) {
            return 0;
        }

        int manaReceived = Math.min(mana.capacity - mana.mana, Math.min(mana.maxReceive, maxReceive));

        if (!simulate) {
            mana.mana += manaReceived;
        }

        return manaReceived;
    }

    @Override
    public int extractMana(String manaType, int maxExtract, boolean simulate) {
        ManaType mana = this.mana.getOrDefault(manaType, null);

        if (mana == null) {
            return 0;
        }

        if (!canExtract(mana)) {
            return 0;
        }

        int manaExtracted = Math.min(mana.mana, Math.min(mana.maxExtract, maxExtract));

        if (!simulate) {
            mana.mana -= manaExtracted;
        }

        return manaExtracted;
    }

    @Override
    public int getManaStored(String manaType) {
        ManaType mana = this.mana.getOrDefault(manaType, null);
        return mana == null ? 0 : mana.mana;

    }

    @Override
    public int getMaxManaStored(String manaType) {
        ManaType mana = this.mana.getOrDefault(manaType, null);
        return mana == null ? 0 : mana.capacity;

    }

    @Override
    public boolean canExtract(String manaType) {
        return canExtract(mana.getOrDefault(manaType, null));
    }

    private boolean canExtract(ManaType manaType) {
        return manaType != null && manaType.maxExtract > 0;
    }

    @Override
    public boolean canReceive(String manaType) {
        return canReceive(mana.getOrDefault(manaType, null));
    }

    @Override
    public Iterable<ManaType> getAllMana() {
        return mana.values();
    }

    private void setMana(String manaType, int value) {
        mana.get(manaType).mana = value;
    }

    private boolean canReceive(ManaType manaType) {
        return manaType != null && manaType.maxReceive > 0 && manaType.mana < manaType.capacity;
    }

    @Override
    public CompoundTag serializeNBT() {
        CompoundTag tag = new CompoundTag();
        tag.putInt("mana", mana.get(DIORITE_TYPE).mana);
        return tag;
    }

    @Override
    public void deserializeNBT(CompoundTag tag) {
        setMana(DIORITE_TYPE, tag.getInt("mana"));
    }
}
